using System;
using System.Collections.Generic;
using System.Linq;

namespace MT5Trade.Models
{
    /// <summary>
    /// 资金利用率动态调整优化器
    /// 基于市场波动率、账户余额、历史表现动态优化资金使用效率
    /// 在保证安全的前提下最大化资金利用率
    /// </summary>
    public class FundUtilizationOptimizer
    {
        #region 常量定义

        /// <summary>
        /// 默认基础利用率（70%）
        /// </summary>
        public const double DEFAULT_BASE_UTILIZATION = 0.70;

        /// <summary>
        /// 最大利用率上限（90%）
        /// </summary>
        public const double MAX_UTILIZATION_LIMIT = 0.90;

        /// <summary>
        /// 最小利用率下限（30%）
        /// </summary>
        public const double MIN_UTILIZATION_LIMIT = 0.30;

        /// <summary>
        /// 安全边际最低资金比例（20%）
        /// </summary>
        public const double SAFETY_MARGIN_RATIO = 0.20;

        /// <summary>
        /// 波动率影响系数
        /// </summary>
        public const double VOLATILITY_IMPACT_COEFFICIENT = 0.5;

        /// <summary>
        /// 历史表现权重系数
        /// </summary>
        public const double PERFORMANCE_WEIGHT_COEFFICIENT = 0.3;

        /// <summary>
        /// 账户健康度权重系数
        /// </summary>
        public const double ACCOUNT_HEALTH_WEIGHT = 0.4;

        /// <summary>
        /// 利用率调整步长
        /// </summary>
        public const double UTILIZATION_ADJUSTMENT_STEP = 0.05;

        /// <summary>
        /// 风险预警阈值（85%）
        /// </summary>
        public const double RISK_WARNING_THRESHOLD = 0.85;

        /// <summary>
        /// 历史窗口天数
        /// </summary>
        public const int PERFORMANCE_WINDOW_DAYS = 30;

        #endregion

        #region 数据结构定义

        /// <summary>
        /// 资金利用率调整结果
        /// </summary>
        public class UtilizationOptimizationResult
        {
            /// <summary>推荐资金利用率</summary>
            public double RecommendedUtilization { get; set; }

            /// <summary>当前波动率状态</summary>
            public ATRCalculator.VolatilityEnvironment VolatilityState { get; set; }

            /// <summary>账户安全边际</summary>
            public double SafetyMargin { get; set; }

            /// <summary>历史表现评分</summary>
            public double PerformanceScore { get; set; }

            /// <summary>风险等级</summary>
            public RiskLevel RiskLevel { get; set; }

            /// <summary>调整理由</summary>
            public string AdjustmentReason { get; set; }

            /// <summary>预警信息</summary>
            public List<string> Warnings { get; set; }

            /// <summary>置信度</summary>
            public double Confidence { get; set; }

            public UtilizationOptimizationResult()
            {
                Warnings = new List<string>();
                Confidence = 0.5;
            }
        }

        /// <summary>
        /// 账户财务状况
        /// </summary>
        public class AccountFinancialStatus
        {
            /// <summary>总资金</summary>
            public double TotalCapital { get; set; }

            /// <summary>可用资金</summary>
            public double AvailableCapital { get; set; }

            /// <summary>已使用资金</summary>
            public double UsedCapital { get; set; }

            /// <summary>浮动盈亏</summary>
            public double FloatingPnL { get; set; }

            /// <summary>当前净值</summary>
            public double NetWorth { get; set; }

            /// <summary>当前利用率</summary>
            public double CurrentUtilization => TotalCapital > 0 ? UsedCapital / TotalCapital : 0;
        }

        /// <summary>
        /// 历史表现指标
        /// </summary>
        public class PerformanceMetrics
        {
            /// <summary>平均日收益率</summary>
            public double AverageDailyReturn { get; set; }

            /// <summary>收益波动率</summary>
            public double ReturnVolatility { get; set; }

            /// <summary>夏普比率</summary>
            public double SharpeRatio { get; set; }

            /// <summary>最大回撤</summary>
            public double MaxDrawdown { get; set; }

            /// <summary>胜率</summary>
            public double WinRate { get; set; }

            /// <summary>平均盈亏比</summary>
            public double ProfitLossRatio { get; set; }

            /// <summary>连续盈利天数</summary>
            public int ConsecutiveProfitDays { get; set; }

            /// <summary>连续亏损天数</summary>
            public int ConsecutiveLossDays { get; set; }
        }

        // 注意：VolatilityEnvironment枚举定义在ATRCalculator中，这里直接使用

        /// <summary>
        /// 风险等级枚举
        /// </summary>
        public enum RiskLevel
        {
            Safe = 0,     // 安全
            Moderate = 1, // 适中
            High = 2,     // 高风险
            Critical = 3  // 危险
        }

        #endregion

        #region 私有字段

        private readonly BankruptcyModel _bankruptcyModel;
        private readonly VolatilityClusterAnalyzer _volatilityAnalyzer;
        private readonly List<double> _performanceHistory;
        private double _lastOptimizedUtilization;
        private DateTime _lastOptimizationTime;
        private int _consecutiveAdjustments;

        #endregion

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        public FundUtilizationOptimizer()
        {
            _bankruptcyModel = new BankruptcyModel();
            _volatilityAnalyzer = new VolatilityClusterAnalyzer();
            _performanceHistory = new List<double>();
            _lastOptimizedUtilization = DEFAULT_BASE_UTILIZATION;
            _lastOptimizationTime = DateTime.Now;
            _consecutiveAdjustments = 0;
        }

        #endregion

        #region 主要方法

        /// <summary>
        /// 计算最优资金利用率
        /// 综合考虑波动率、账户状况、历史表现等因素
        /// </summary>
        /// <param name="accountStatus">账户财务状况</param>
        /// <param name="performanceMetrics">历史表现指标</param>
        /// <param name="marketVolatility">当前市场波动率</param>
        /// <param name="priceHistory">价格历史数据</param>
        /// <returns>优化结果</returns>
        public UtilizationOptimizationResult OptimizeUtilization(
            AccountFinancialStatus accountStatus,
            PerformanceMetrics performanceMetrics,
            double marketVolatility,
            double[] priceHistory = null)
        {
            // 参数验证
            if (accountStatus == null)
                throw new ArgumentNullException(nameof(accountStatus));
            if (performanceMetrics == null)
                throw new ArgumentNullException(nameof(performanceMetrics));

            var result = new UtilizationOptimizationResult();
            
            try
            {
                // 检查输入数据有效性
                bool hasInvalidInput = marketVolatility < 0;

                // 1. 分析波动率环境
                result.VolatilityState = AnalyzeVolatilityEnvironment(marketVolatility, priceHistory);

                // 2. 评估历史表现
                result.PerformanceScore = EvaluatePerformanceScore(performanceMetrics);

                // 3. 计算账户安全边际
                result.SafetyMargin = CalculateSafetyMargin(accountStatus);

                // 4. 综合计算最优利用率
                result.RecommendedUtilization = CalculateOptimalUtilization(
                    result.VolatilityState, result.PerformanceScore, result.SafetyMargin, accountStatus);

                // 5. 评估风险等级
                result.RiskLevel = AssessRiskLevel(result.RecommendedUtilization, accountStatus, Math.Max(0, marketVolatility));

                // 6. 生成调整理由和预警
                GenerateAdjustmentReason(result, accountStatus, performanceMetrics);
                GenerateWarnings(result, accountStatus, Math.Max(0, marketVolatility));

                // 7. 计算置信度
                result.Confidence = CalculateConfidence(result, performanceMetrics);
                
                // 对于无效输入，显著降低置信度
                if (hasInvalidInput)
                {
                    result.Confidence *= 0.3; // 降低到原来的30%
                    result.Warnings.Add("检测到无效输入数据，建议验证数据质量");
                }

                // 8. 更新内部状态
                UpdateInternalState(result.RecommendedUtilization);

                return result;
            }
            catch (Exception ex)
            {
                result.RecommendedUtilization = DEFAULT_BASE_UTILIZATION;
                result.Warnings.Add($"优化计算出现异常，使用默认利用率：{ex.Message}");
                result.Confidence = 0.1;
                return result;
            }
        }

        /// <summary>
        /// 实时监控资金利用率状态
        /// </summary>
        /// <param name="accountStatus">账户状况</param>
        /// <returns>监控报告</returns>
        public UtilizationMonitoringReport MonitorUtilization(AccountFinancialStatus accountStatus)
        {
            var report = new UtilizationMonitoringReport
            {
                CurrentUtilization = accountStatus.CurrentUtilization,
                OptimalUtilization = _lastOptimizedUtilization,
                Deviation = Math.Abs(accountStatus.CurrentUtilization - _lastOptimizedUtilization),
                LastOptimizationTime = _lastOptimizationTime
            };

            // 检查是否需要重新优化
            report.RequiresReoptimization = CheckReoptimizationNeeded(accountStatus, report.Deviation);

            // 生成监控预警
            GenerateMonitoringAlerts(report, accountStatus);

            return report;
        }

        #endregion

        #region 私有辅助方法

        /// <summary>
        /// 分析波动率环境
        /// </summary>
        private ATRCalculator.VolatilityEnvironment AnalyzeVolatilityEnvironment(double marketVolatility, double[] priceHistory)
        {
            if (priceHistory != null && priceHistory.Length >= VolatilityClusterAnalyzer.MIN_VOLATILITY_SAMPLES)
            {
                var volatilityData = CalculateVolatilitySequence(priceHistory);
                var clusterResult = _volatilityAnalyzer.PerformKMeansClusterAnalysis(volatilityData);
                
                if (clusterResult != null && clusterResult.IsConverged)
                {
                    return (ATRCalculator.VolatilityEnvironment)(int)clusterResult.CurrentState;
                }
            }

            // 回退到简单阈值判断
            if (marketVolatility < BankruptcyModel.LOW_VOLATILITY_THRESHOLD)
                return ATRCalculator.VolatilityEnvironment.Low;
            else if (marketVolatility < BankruptcyModel.MEDIUM_VOLATILITY_THRESHOLD)
                return ATRCalculator.VolatilityEnvironment.Medium;
            else
                return ATRCalculator.VolatilityEnvironment.High;
        }

        /// <summary>
        /// 计算价格序列的波动率
        /// </summary>
        private double[] CalculateVolatilitySequence(double[] prices)
        {
            var returns = new double[prices.Length - 1];
            for (int i = 1; i < prices.Length; i++)
            {
                returns[i - 1] = Math.Log(prices[i] / prices[i - 1]);
            }

            var volatilities = new double[returns.Length - 20 + 1];
            for (int i = 0; i < volatilities.Length; i++)
            {
                var window = returns.Skip(i).Take(20).ToArray();
                volatilities[i] = CalculateStandardDeviation(window);
            }

            return volatilities;
        }

        /// <summary>
        /// 评估历史表现评分
        /// </summary>
        private double EvaluatePerformanceScore(PerformanceMetrics metrics)
        {
            var score = 0.5; // 基础分数

            // 夏普比率贡献 (30%)
            if (metrics.SharpeRatio > 0)
            {
                score += Math.Min(metrics.SharpeRatio * 0.1, 0.3);
            }

            // 胜率贡献 (25%)
            score += (metrics.WinRate - 0.5) * 0.5;

            // 盈亏比贡献 (25%)
            if (metrics.ProfitLossRatio > 1.0)
            {
                score += Math.Min((metrics.ProfitLossRatio - 1.0) * 0.25, 0.25);
            }

            // 最大回撤惩罚 (20%)
            score -= Math.Min(metrics.MaxDrawdown * 2, 0.2);

            // 连续表现调整
            if (metrics.ConsecutiveProfitDays > 5)
                score += 0.05;
            if (metrics.ConsecutiveLossDays > 3)
                score -= 0.05;

            return Math.Max(0, Math.Min(1, score));
        }

        /// <summary>
        /// 计算账户安全边际
        /// </summary>
        private double CalculateSafetyMargin(AccountFinancialStatus accountStatus)
        {
            var availableRatio = accountStatus.AvailableCapital / accountStatus.TotalCapital;
            var floatingPnLRatio = accountStatus.FloatingPnL / accountStatus.TotalCapital;
            var netWorthRatio = accountStatus.NetWorth / accountStatus.TotalCapital;

            // 修正算法：安全边际主要由可用资金决定，净值主要用作调整系数
            var baseMargin = availableRatio; // 基础安全边际基于可用资金比例
            var floatingPnLAdjustment = Math.Max(-0.1, floatingPnLRatio * 0.5); // 浮动盈亏调整，最大负面影响10%
            var netWorthAdjustment = Math.Max(0, (netWorthRatio - 1.0) * 0.2); // 净值超过100%时的正面调整
            
            var safetyMargin = baseMargin + floatingPnLAdjustment + netWorthAdjustment;
            
            return Math.Max(0, Math.Min(1, safetyMargin));
        }

        /// <summary>
        /// 计算最优利用率
        /// </summary>
        private double CalculateOptimalUtilization(ATRCalculator.VolatilityEnvironment volatilityState, 
            double performanceScore, double safetyMargin, AccountFinancialStatus accountStatus)
        {
            var baseUtilization = DEFAULT_BASE_UTILIZATION;

            // 波动率调整
            var volatilityAdjustment = GetVolatilityAdjustment(volatilityState);
            
            // 表现调整
            var performanceAdjustment = (performanceScore - 0.5) * PERFORMANCE_WEIGHT_COEFFICIENT;
            
            // 安全边际调整
            var safetyAdjustment = (safetyMargin - SAFETY_MARGIN_RATIO) * ACCOUNT_HEALTH_WEIGHT;

            // 综合计算
            var optimalUtilization = baseUtilization + volatilityAdjustment + performanceAdjustment + safetyAdjustment;

            // 应用约束条件
            optimalUtilization = Math.Max(MIN_UTILIZATION_LIMIT, Math.Min(MAX_UTILIZATION_LIMIT, optimalUtilization));

            // 平滑调整，避免剧烈波动
            var maxAdjustment = UTILIZATION_ADJUSTMENT_STEP * 3;
            var adjustmentDiff = optimalUtilization - _lastOptimizedUtilization;
            if (Math.Abs(adjustmentDiff) > maxAdjustment)
            {
                optimalUtilization = _lastOptimizedUtilization + Math.Sign(adjustmentDiff) * maxAdjustment;
            }

            return optimalUtilization;
        }

        /// <summary>
        /// 获取波动率调整系数
        /// </summary>
        private double GetVolatilityAdjustment(ATRCalculator.VolatilityEnvironment volatilityState)
        {
            return volatilityState switch
            {
                ATRCalculator.VolatilityEnvironment.Low => VOLATILITY_IMPACT_COEFFICIENT * 0.15,   // 低波动提高利用率7.5%
                ATRCalculator.VolatilityEnvironment.Medium => 0,                                     // 中等波动不调整
                ATRCalculator.VolatilityEnvironment.High => -VOLATILITY_IMPACT_COEFFICIENT * 0.4,  // 高波动降低利用率20%
                ATRCalculator.VolatilityEnvironment.Extreme => -VOLATILITY_IMPACT_COEFFICIENT * 0.6, // 极端波动大幅降低利用率30%
                _ => 0
            };
        }

        /// <summary>
        /// 评估风险等级
        /// </summary>
        private RiskLevel AssessRiskLevel(double utilization, AccountFinancialStatus accountStatus, double volatility)
        {
            var riskScore = 0.0;

            // 利用率风险
            riskScore += Math.Max(0, (utilization - 0.7) * 2);

            // 波动率风险
            riskScore += volatility * 10;

            // 账户健康度风险
            var healthScore = accountStatus.NetWorth / accountStatus.TotalCapital;
            riskScore += Math.Max(0, (1.0 - healthScore) * 2);

            return riskScore switch
            {
                < 0.2 => RiskLevel.Safe,
                < 0.4 => RiskLevel.Moderate,
                < 0.6 => RiskLevel.High,
                _ => RiskLevel.Critical
            };
        }

        /// <summary>
        /// 生成调整理由
        /// </summary>
        private void GenerateAdjustmentReason(UtilizationOptimizationResult result, 
            AccountFinancialStatus accountStatus, PerformanceMetrics performanceMetrics)
        {
            var reasons = new List<string>();

            var utilizationChange = result.RecommendedUtilization - accountStatus.CurrentUtilization;

            if (Math.Abs(utilizationChange) > 0.02)
            {
                var direction = utilizationChange > 0 ? "提高" : "降低";
                reasons.Add($"建议{direction}资金利用率{Math.Abs(utilizationChange):P1}");

                // 具体原因
                if (result.VolatilityState == ATRCalculator.VolatilityEnvironment.High && utilizationChange < 0)
                    reasons.Add("当前市场波动率较高，降低风险敞口");
                
                if (result.PerformanceScore > 0.7 && utilizationChange > 0)
                    reasons.Add("历史表现优秀，可适度提高资金使用");
                
                if (result.SafetyMargin < SAFETY_MARGIN_RATIO && utilizationChange < 0)
                    reasons.Add("账户安全边际不足，需保留更多资金");
            }
            else
            {
                reasons.Add("当前利用率已接近最优水平，无需大幅调整");
            }

            result.AdjustmentReason = string.Join("；", reasons);
        }

        /// <summary>
        /// 生成预警信息
        /// </summary>
        private void GenerateWarnings(UtilizationOptimizationResult result, 
            AccountFinancialStatus accountStatus, double marketVolatility)
        {
            // 高利用率预警
            if (result.RecommendedUtilization > RISK_WARNING_THRESHOLD)
            {
                result.Warnings.Add($"资金利用率({result.RecommendedUtilization:P1})接近上限，请谨慎操作");
            }

            // 高波动率预警
            if (marketVolatility > BankruptcyModel.MEDIUM_VOLATILITY_THRESHOLD)
            {
                result.Warnings.Add("市场波动率较高，建议降低仓位规模");
            }

            // 安全边际不足预警
            if (result.SafetyMargin < SAFETY_MARGIN_RATIO)
            {
                result.Warnings.Add("账户安全边际不足，建议保留更多现金");
            }

            // 浮动亏损预警
            if (accountStatus.FloatingPnL < -accountStatus.TotalCapital * 0.05)
            {
                result.Warnings.Add("当前浮动亏损较大，建议暂缓增加仓位");
            }

            // 风险等级预警
            if (result.RiskLevel >= RiskLevel.High)
            {
                result.Warnings.Add("当前风险等级较高，请密切关注市场变化");
            }
        }

        /// <summary>
        /// 计算置信度
        /// </summary>
        private double CalculateConfidence(UtilizationOptimizationResult result, PerformanceMetrics metrics)
        {
            var confidence = 0.5; // 基础置信度

            // 历史数据充分性
            if (_performanceHistory.Count > PERFORMANCE_WINDOW_DAYS)
                confidence += 0.2;

            // 表现稳定性
            if (metrics.ReturnVolatility < 0.02)
                confidence += 0.15;

            // 风险等级合理性
            if (result.RiskLevel <= RiskLevel.Moderate)
                confidence += 0.15;

            return Math.Max(0.1, Math.Min(1.0, confidence));
        }

        /// <summary>
        /// 更新内部状态
        /// </summary>
        private void UpdateInternalState(double newUtilization)
        {
            var utilizationChange = Math.Abs(newUtilization - _lastOptimizedUtilization);
            
            if (utilizationChange > UTILIZATION_ADJUSTMENT_STEP)
            {
                _consecutiveAdjustments++;
            }
            else
            {
                _consecutiveAdjustments = 0;
            }

            _lastOptimizedUtilization = newUtilization;
            _lastOptimizationTime = DateTime.Now;
        }

        /// <summary>
        /// 检查是否需要重新优化
        /// </summary>
        private bool CheckReoptimizationNeeded(AccountFinancialStatus accountStatus, double deviation)
        {
            // 偏差过大
            if (deviation > 0.1)
                return true;

            // 距离上次优化时间过长
            if ((DateTime.Now - _lastOptimizationTime).TotalHours > 4)
                return true;

            // 账户状况发生重大变化
            if (accountStatus.FloatingPnL / accountStatus.TotalCapital < -0.1)
                return true;

            return false;
        }

        /// <summary>
        /// 生成监控预警
        /// </summary>
        private void GenerateMonitoringAlerts(UtilizationMonitoringReport report, AccountFinancialStatus accountStatus)
        {
            report.Alerts = new List<string>();

            if (report.Deviation > 0.15)
            {
                report.Alerts.Add("实际利用率与最优利用率偏差过大");
            }

            if (accountStatus.CurrentUtilization > MAX_UTILIZATION_LIMIT)
            {
                report.Alerts.Add("当前资金利用率超出安全上限");
            }

            if (_consecutiveAdjustments > 5)
            {
                report.Alerts.Add("连续调整次数过多，可能存在策略不稳定");
            }
        }

        /// <summary>
        /// 计算标准差
        /// </summary>
        private double CalculateStandardDeviation(double[] values)
        {
            if (values.Length == 0) return 0;
            
            var mean = values.Average();
            var sumOfSquares = values.Sum(x => Math.Pow(x - mean, 2));
            return Math.Sqrt(sumOfSquares / values.Length);
        }

        #endregion

        #region 公共实用方法

        /// <summary>
        /// 获取优化器状态信息
        /// </summary>
        /// <returns>状态描述</returns>
        public string GetOptimizerStatus()
        {
            return $"FundUtilizationOptimizer状态：" +
                   $"上次优化利用率：{_lastOptimizedUtilization:P2}，" +
                   $"上次优化时间：{_lastOptimizationTime:yyyy-MM-dd HH:mm:ss}，" +
                   $"连续调整次数：{_consecutiveAdjustments}，" +
                   $"历史数据点数：{_performanceHistory.Count}";
        }

        /// <summary>
        /// 添加表现数据点
        /// </summary>
        /// <param name="performanceValue">表现值</param>
        public void AddPerformanceDataPoint(double performanceValue)
        {
            _performanceHistory.Add(performanceValue);
            
            // 保持历史数据在合理范围内
            if (_performanceHistory.Count > PERFORMANCE_WINDOW_DAYS * 2)
            {
                _performanceHistory.RemoveAt(0);
            }
        }

        /// <summary>
        /// 重置优化器状态
        /// </summary>
        public void ResetOptimizer()
        {
            _lastOptimizedUtilization = DEFAULT_BASE_UTILIZATION;
            _consecutiveAdjustments = 0;
            _performanceHistory.Clear();
        }

        #endregion
    }

    /// <summary>
    /// 资金利用率监控报告
    /// </summary>
    public class UtilizationMonitoringReport
    {
        /// <summary>当前利用率</summary>
        public double CurrentUtilization { get; set; }

        /// <summary>最优利用率</summary>
        public double OptimalUtilization { get; set; }

        /// <summary>偏差程度</summary>
        public double Deviation { get; set; }

        /// <summary>是否需要重新优化</summary>
        public bool RequiresReoptimization { get; set; }

        /// <summary>上次优化时间</summary>
        public DateTime LastOptimizationTime { get; set; }

        /// <summary>监控预警</summary>
        public List<string> Alerts { get; set; }

        public UtilizationMonitoringReport()
        {
            Alerts = new List<string>();
        }
    }
}
